package me.flyray.bsin.gateway.portal;

import com.alibaba.fastjson.JSONObject;
import com.alipay.sofa.rpc.api.GenericService;
import com.alipay.sofa.rpc.common.json.JSON;
import com.alipay.sofa.rpc.config.ConsumerConfig;
import com.alipay.sofa.rpc.registry.RegistryFactory;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import io.seata.saga.engine.StateMachineEngine;
import io.seata.saga.statelang.domain.ExecutionStatus;
import io.seata.saga.statelang.domain.StateMachineInstance;
import lombok.extern.log4j.Log4j2;
import me.flyray.bsin.exception.BusinessException;
import me.flyray.bsin.gateway.common.ApiResult;
import me.flyray.bsin.gateway.context.BsinContextBuilder;
import me.flyray.bsin.gateway.domain.BsinChoreographyServiceDo;
import me.flyray.bsin.gateway.service.BsinChoreographyServiceService;
import me.flyray.bsin.gateway.service.BsinIpfsRequestHandlerService;
import me.flyray.bsin.gateway.service.BsinStateMachineServiceTaskProxy;
import me.flyray.bsin.oss.ipfs.BsinIpfsService;
import me.flyray.bsin.utils.BsinServiceInvokeUtil;

/**
 * 管理后台网关入口
 */
@Log4j2
@RestController
public class BsinAdminPortal {


    @Value("${bsin.bigan.default.tenant-id}")
    private String tenantId;
    @Value("${bsin.bigan.default.app-id}")
    private String appId;
    @Autowired
    public BsinContextBuilder bsinContextBuilder;
    @Autowired
    public BsinServiceInvokeUtil bsinServiceInvoke;
//    @Autowired
//    private BsinChoreographyServiceService choreographyServiceService;
    @Autowired
    private BsinIpfsRequestHandlerService bsinIpfsRequestHandlerService;
    @Autowired
    private BsinIpfsService bsinIpfsService;
//    @Autowired
//    private BsinStateMachineServiceTaskProxy bsinStateMachineService;

    private static ConcurrentHashMap<String, GenericService> concurrentHashMap = new ConcurrentHashMap<String, GenericService>();

    /**
     * http请求入口
     * 1、拼装请求参数
     * 2、唤起服务: 泛化 编排
     * 3、拼装响应报文
     * @param req
     * @return
     */
    // TODO 修改为 admin-gateway
    @PostMapping("/gateway")
    public ApiResult portal(@RequestBody Map<String, Object> req) throws IOException {
        log.info("gateway请求参数:{}", JSON.toJSONString(req));
        // 系统参数
        String serviceName = (String) req.get("serviceName");
        String methodName = (String) req.get("methodName");
        String version = (String) req.get("version");
        Map<String, Object> bizParams = (Map<String, Object>) req.get("bizParams");

        ApiResult ipfsResult = bsinIpfsRequestHandlerService.ipfsRequestHandler(methodName, bizParams);
        if (ipfsResult != null) {
            return ipfsResult;
        }

        // TODO 重新抽离封装
        if ("metadataUpload".equals(methodName)) {
            log.info("metadataUpload请求参数:{}", JSON.toJSONString(req));
            String metadataName = (String) bizParams.get("metadataName");
            String metadataContent = (String) bizParams.get("metadataContent");
            // 讲上传到本地的文件上传到ipfs上
            byte[] data = metadataContent.getBytes();
            JSONObject resultJson = bsinIpfsService.ipfsAdd(data, metadataName + ".json");
            log.info(String.format("文件上传成功,Hash值为: %s", resultJson.toString()));
            Map<String, Object> resultData = new HashMap<String, Object>();
            resultData.put("fileUrl", resultJson.get("fileUrl"));
            resultData.put("fileHash", resultJson.get("fileHash"));
            return ApiResult.ok(resultData);
        }

        // 1、拼装报文
        Map<String, Object> reqParam = bsinContextBuilder.buildReqMessage(req);
        log.info("拼装报文:{}", reqParam);
        // 2、获取编排服务
//        BsinChoreographyServiceDo choreographyServiceDo = choreographyServiceService.getChoreographyServiceByServiceAndMethod(req);
//        if (choreographyServiceDo != null) {
//            // 2、编排服务调用
//            ApiResult apiResult = bsinStateMachineService.choreographyInvoke(choreographyServiceDo, reqParam);
//            return apiResult;
//        }
        // 3、泛化调用RPC服务
        Map result = null;
        try {
            result = bsinServiceInvoke.genericInvoke(serviceName, methodName, version, reqParam);
            /*if (StringUtils.isNotBlank(detailMessage)){
                log.info("open api 调用异常 返回参数:{}", detailMessage);
                return ApiResult.fail(detailMessage);
            }*/
        } catch (BusinessException e) {
            log.error(e.getMessage(), e);
            throw e;
        }
        // 4、响应报文处理
        ApiResult apiResult = bsinContextBuilder.buildResMessage(serviceName, methodName, result);
        log.info("gateway响应报文返回参数:{}", JSON.toJSONString(apiResult));
        return apiResult;
    }

}

